//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.TridentWordAddIn.Common;
using System.Xml;

namespace Microsoft.TridentWordAddIn.Presentation
{
    /// <summary>
    /// TypeInitializer base user control
    /// </summary>
    public partial class TypeInitializerUserControl : UserControl
    {
        private string type;
        private string value;
        private bool isCustomType;
        private bool isValid = true;
        private List<ComplexInitializer> fields = new List<ComplexInitializer>();
        /// <summary>
        /// Occurs when [on value changed].
        /// </summary>
        public event EventHandler<EventArgs> OnValueChanged;
        
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeInitializerUserControl"/> class.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="type">The type.</param>
        /// <param name="customType">if set to <c>true</c> [custom type].</param>
        public TypeInitializerUserControl(object value, string type, bool customType)
        {
            InitializeComponent();
            this.type = type;
            this.value = value == null ? string.Empty : value.ToString();
            this.isCustomType = customType;

            SetValue();
        }

        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>The value.</value>
        public string Value
        {
            get
            {
                return this.value;
            }
            set
            {
                this.value = value;
                //this.txtValue.Text = this.value;
                //toolTip.SetToolTip(this.txtValue, this.value);
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is valid.
        /// </summary>
        /// <value><c>true</c> if this instance is valid; otherwise, <c>false</c>.</value>
        public bool IsValid
        {
            get
            {
                return this.isValid;
            }
        }

        /// <summary>
        /// Sets the value.
        /// </summary>
        private void SetValue()
        {
            if (this.isCustomType)
            {
                ParseXml(value.ToString());
                string complexValue = this.GetComplexValue();
                this.txtValue.Text = complexValue;
                toolTip.SetToolTip(this.txtValue, complexValue);
            }
            else
            {
                this.txtValue.Text = this.value;
                toolTip.SetToolTip(this.txtValue, this.value);
            }
        }

        /// <summary>
        /// Gets the complex value.
        /// </summary>
        /// <returns></returns>
        private string GetComplexValue()
        {
            StringBuilder result = new StringBuilder();
            foreach (ComplexInitializer initializer in this.fields)
            {
                if (!initializer.IsRoot)
                {
                    result.Append(initializer.Label);
                    result.Append(":");
                    result.Append(initializer.Value);
                    result.Append(" ");
                }
            }

            return result.ToString();
        }

        /// <summary>
        /// Parses the XML.
        /// </summary>
        /// <param name="value">The value.</param>
        private void ParseXml(string value)
        {
            fields.Clear();
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(value);
            foreach (XmlNode node in xmlDocument.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    fields.Add(new ComplexInitializer(node.Name, node.InnerText, true));
                    foreach (XmlNode childNode in node.ChildNodes)
                    {
                        fields.Add(new ComplexInitializer(childNode.Name, childNode.InnerText, false));
                    }
                }
            }

            xmlDocument = null;
        }

        /// <summary>
        /// Handles the Click event of the btnShowCustomDialog control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnShowCustomDialog_Click(object sender, EventArgs e)
        {
            this.isValid = true;
            BaseTypeInitializer baseTypeInitializer;
            switch (this.type)
            {
                case "System.IO.FileInfo":
                    baseTypeInitializer = new FileInfoUserControl(true);
                    break;
                case "System.IO.DirectoryInfo":
                    baseTypeInitializer = new FileInfoUserControl(false);
                    break;
                default:
                    baseTypeInitializer = new CustomTypeInitializer(fields);
                    break;
            }

            baseTypeInitializer.SetResult(this.value);
            TypeInitializerHolderForm containerForm = new TypeInitializerHolderForm();
            containerForm.AddUserControl(baseTypeInitializer);
            
            if (containerForm.ShowDialog() == DialogResult.OK)
            {
                value = baseTypeInitializer.GetResult().ToString();
                this.isValid = baseTypeInitializer.IsValid;

                SetValue();

                if (OnValueChanged != null)
                {
                    this.OnValueChanged(this, EventArgs.Empty);
                }
            }
        }
    }
}
